package io.gitee.twoke.generator.engine;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public abstract class GenerateEngines {

    public static final String NAME_DEFAULT = "default";
    protected static boolean isInitialized;
    protected static Map<String, GenerateEngine> generateEngines = new HashMap<String, GenerateEngine>();

    public synchronized static void init() {
        if (!isInitialized()) {
            if (generateEngines == null) {
                // Create new map to store process-engines if current map is
                // null
                generateEngines = new HashMap<String, GenerateEngine>();
            }

            setInitialized(true);
        } else {
            log.info("Generate engines already initialized");
        }
    }

    public static void registerGenerateEngine(GenerateEngine processEngine) {
        generateEngines.put(processEngine.getName(), processEngine);
    }

    /**
     * Unregisters the given process engine.
     */
    public static void unregister(GenerateEngine processEngine) {
        generateEngines.remove(processEngine.getName());
    }

    public static GenerateEngine getDefaultGenerateEngine() {
        return getGenerateEngine(NAME_DEFAULT);
    }

    /**
     * obtain a process engine by name.
     *
     * @param generateEngineName
     *          is the name of the process engine or null for the default process engine.
     */
    public static GenerateEngine getGenerateEngine(String generateEngineName) {
        if (!isInitialized()) {
            init();
        }
        return generateEngines.get(generateEngineName);
    }

    public synchronized static void destroy() {
        if (isInitialized()) {
            Map<String, GenerateEngine> engines = new HashMap<String, GenerateEngine>(generateEngines);
            generateEngines = new HashMap<String, GenerateEngine>();

            for (String generateEngineName : engines.keySet()) {
                GenerateEngine generateEngine = engines.get(generateEngineName);
                try {
                    generateEngine.close();
                } catch (Exception e) {
                    log.error("exception while closing {}", (generateEngineName == null ? "the default process engine" : "process engine " + generateEngineName), e);
                }
            }

            setInitialized(false);
        }
    }

    public static boolean isInitialized() {
        return isInitialized;
    }

    public static void setInitialized(boolean isInitialized) {
        GenerateEngines.isInitialized = isInitialized;
    }

}